package org.dce.screencapturer.util;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;

import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoableEdit;

public class UndoablePropertyChange 
	implements UndoableEdit{

	private Object source;
	private String propertyName;
	private Object oldValue;
	private Object newValue;
	
	private boolean undone = true;

	public UndoablePropertyChange(
			Object source,
			String propertyName,
			Object oldValue,
			Object newValue) {
		this.source = source;
		this.propertyName = propertyName;
		this.oldValue = oldValue;
		this.newValue = newValue;
	}
	@Override
	public boolean addEdit(UndoableEdit anEdit) {
		return false;
	}
	@Override
	public boolean canRedo() {
		return undone;
	}
	@Override
	public boolean canUndo() {
		return !undone;
	}
	@Override
	public void die() {
	}
	@Override
	public String getPresentationName() {
		return propertyName;
	}
	@Override
	public String getRedoPresentationName() {
		return "Redo "+propertyName;
	}
	@Override
	public String getUndoPresentationName() {
		return "Undo "+propertyName;
	}
	@Override
	public boolean isSignificant() {
		return true;
	}
	@Override
	public void redo() throws CannotRedoException {
		setProperty(newValue);
		undone = false;
	}
	@Override
	public boolean replaceEdit(UndoableEdit anEdit) {
		return false;
	}
	@Override
	public void undo() throws CannotUndoException {
		setProperty(oldValue);
		undone = true;
	}
	
	private void setProperty(Object newValue){

		try {
			PropertyDescriptor[] descriptors = Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors();
			
			for (PropertyDescriptor descriptor:descriptors){
				if (descriptor.getName().equals(propertyName)){
					descriptor.getWriteMethod().invoke(source, newValue);
				}
			}
		}catch (Exception ex){
		}
	}
	
}
